package com.veer.shop.utils;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.springframework.web.multipart.MultipartFile;
import com.veer.shop.config.Constants;
import com.veer.shop.config.OpResult;
import net.coobird.thumbnailator.Thumbnails;

/**
 * 文件操作工具类
 * 
 * @author WangBin
 * 2020年10月6日-下午4:12:50
 */
public class FileUtil {
	
	/**
	 * 将 base64 转存为文件
	 * 
	 * @param fileName
	 * @param base64
	 * @param savePath
	 * @return boolean 
	 */
	public static boolean base64ToFile(String fileName, String base64, String savePath) {
		boolean result = false;
		
		File file = null;

		// 检查保存目录
		File dir = new File(savePath);
		if(!dir.exists() && !dir.isDirectory()) {
			dir.mkdirs();
		}
		
		BufferedOutputStream bos = null;
		FileOutputStream fos = null;
		
		try {
			// 去除 base64 中的 data:image/jpeg;base64, 类似字符
			base64 = base64.substring(base64.indexOf( "," ) + 1);
			//base64 = base64.replace(oldChar, newChar)
			byte[] bytes = Base64.getDecoder().decode(base64);
			file = new File(savePath.concat(fileName));
			fos = new FileOutputStream(file);
			bos = new BufferedOutputStream(fos);
			bos.write(bytes);
			
			result = true;
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (bos != null) {
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
		}
		
		return result;
	}
	
	/**
	 * 获取文件的格式(png、mp4、...)
	 * 
	 * @param base64
	 * @return
	 */
	public static String getBase64FileFormat(String base64) {
		String regex = "/(.+);base64";
		Pattern pattern = Pattern.compile(regex);
		Matcher matcher = pattern.matcher(base64);
		if(matcher.find()) {
			return matcher.group(1);
		}
		
		return "";
	}
	
	/**
	 * 获取base64文件大小(KB)
	 * 
	 * @param base64
	 */
	public static double getBase64FileSize(String base64) {
		//1.获取base64字符串长度(不含data:audio/wav;base64,文件头)
		int size0 = base64.length();

		//2.获取字符串的尾巴的最后10个字符，用于判断尾巴是否有等号，正常生成的base64文件'等号'不会超过4个
		String tail = base64.substring(size0-10);

		//3.找到等号，把等号也去掉,(等号其实是空的意思,不能算在文件大小里面)
		int equalIndex = tail.indexOf("=");		
		if(equalIndex > 0) {
		  	size0 = size0 - (10 - equalIndex);
        }

	 	//4.计算后得到的文件流大小，单位为字节
		return (size0 -( (double)size0 / 8 ) * 2)/1000;
	}
	
	/**
	 * 获取图片的大尺寸、小尺寸图片(返回相对路径)
	 * 
	 * @param imagePath 原图片路径
	 * @param savePath 储存图片目录
	 * @return
	 */
	public static Map<String, String> getImageMoreSize(String imagePath, String savePath) {
		Map<String, String> moreSizeMap = new HashMap<String, String>();
		moreSizeMap.put("middle_size", "");
		moreSizeMap.put("small_size", "");
		
		// 文件
		File file = new File(imagePath);
		
		// 原图片不存在
		if(!file.exists())return moreSizeMap;
		
		// 获取文件名称
		String fileName = file.getName().substring(0,file.getName().lastIndexOf("."));
		
		// 获取文件格式
		String format = getFileFormat(imagePath, true);
		
		// 中图宽高配置
		String middleWidth = SystemConfigUtil.getConfigValue(Constants.SYSTEM_CONFIG_IMAGE_MIDDLE_WIDTH);
		String middleHeight = SystemConfigUtil.getConfigValue(Constants.SYSTEM_CONFIG_IMAGE_MIDDLE_HEIGTH);
		
		// 小图宽高配置
		String smallWidth = SystemConfigUtil.getConfigValue(Constants.SYSTEM_CONFIG_IMAGE_SMALL_WIDTH);
		String smallHeight = SystemConfigUtil.getConfigValue(Constants.SYSTEM_CONFIG_IMAGE_SMALL_HEIGTH);
		
		// 处理中图
		try {
			
			String middleFileName = fileName
					.concat("_")
					.concat(middleWidth)
					.concat("x")
					.concat(middleHeight)
					.concat(format);
			
			Thumbnails.of(imagePath)
				.size(Integer.parseInt(middleWidth), Integer.parseInt(middleHeight))
				.toFile(savePath.concat(middleFileName));
			
			moreSizeMap.put("middle_size", "/".concat(middleFileName));
		} catch (Exception e) {
			// TODO: handle exception
		}
		
		// 处理小图
		try {
			
			String smallFileName = fileName
					.concat("_")
					.concat(smallWidth)
					.concat("x")
					.concat(smallHeight)
					.concat(format);
			
			Thumbnails.of(imagePath)
				.size(Integer.parseInt(smallWidth), Integer.parseInt(smallHeight))
				.toFile(savePath.concat(smallFileName));
			
			moreSizeMap.put("small_size", "/".concat(smallFileName));
		} catch (Exception e) {
			// TODO: handle exception
		}
		
		return moreSizeMap;
	}
	
	/**
	 * 处理图片水印
	 * 
	 * @param imagePath
	 * @return
	 */
	public static boolean setImageWaterMark(String imagePath) {
		return false;
	}
	
	/**
	 * 根据文件名获取文件格式
	 * 
	 * @param fileName
	 * @param withDot
	 * @return
	 */
	public static String getFileFormat(String fileName, boolean withDot) {
		String format = "";
		int idx = withDot == true ? 0 : 1;
		try {
			format = fileName.substring(fileName.lastIndexOf(".") + idx);
		} catch (Exception e) {
			// TODO: handle exception
		}
		
		return format;
	}
	
	/**
	 * 获取自定义的文件名
	 * 
	 * @return
	 */
	public static String getCustomFileName() {
		return DateTimeUtil.getFormatDate("yyMMdd").concat(EcryptUtil.generateUUID());
	}
	
	/**
	 * 获取导入文件的默认储存根路径
	 * 
	 * @return
	 */
	public static String getImportFileRootPath() {
		String filePath = "";
		try {
			String fileRootPath = SystemConfigUtil.getConfigValue(Constants.SYSTEM_CONFIG_FILE_PATH_ROOT);
			String importFilePath = SystemConfigUtil.getConfigValue(Constants.SYSTEM_CONFIG_IMPORT_FILE_PATH);
			// 文件路径不存在则新建
			filePath = fileRootPath + importFilePath;
			File file = new File(filePath);
			if(!file.exists()) {
				file.mkdirs();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return filePath;
	}
	
	/**
	 * 开始文件上传
	 * 
	 * @param multipartFile
	 * @param filename 服务器文件名
	 * @return
	 */
	public static OpResult<String> upload(MultipartFile multipartFile, String filename) {
		OpResult<String> importResult = new OpResult<String>();
		try {
			// 获取系统上传文件的存储路径
			String importFileRootPath = getImportFileRootPath();
			File file = new File(importFileRootPath + "/" + filename);
			multipartFile.transferTo(file);
			importResult.setFlag(true);
			importResult.setMessage("文件上传成功");
			importResult.setData(file.getAbsolutePath());
		} catch (Exception e) {
			importResult.setMessage(e.getMessage());
			e.printStackTrace();
		}
		return importResult;
	}
}